package com.liulishuo.demo.filedownloaderapplication;

import com.liulishuo.filedownloader.BaseDownloadTask;
import com.liulishuo.filedownloader.FileDownloadListener;
import com.liulishuo.filedownloader.FileDownloadQueueSet;
import com.liulishuo.filedownloader.FileDownloader;
import com.liulishuo.filedownloader.util.FileDownloadUtils;
import com.oszc.bbhmlibrary.androidwrapper.EventHandlerWithCallback;
import com.oszc.bbhmlibrary.utils.MainHandler;
import com.oszc.bbhmlibrary.utils.ResUtil;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.agp.components.*;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.eventhandler.InnerEvent;
import ohos.multimodalinput.event.TouchEvent;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class HybridTestAbility extends Ability {

    private final String TAG = "Demo.HybridActivity";
    private EventHandler uiHandler;
    private final int WHAT_NEED_AUTO_2_BOTTOM = 1;
    private boolean needAuto2Bottom = true;

    @Override
    protected void onStart(Intent intent) {
        super.onStart(intent);
        setUIContent(ResourceTable.Layout_layout_hybrid_task);
        uiHandler = new EventHandlerWithCallback(EventRunner.getMainEventRunner(),new EventHandlerWithCallback.Callback() {
            @Override
            public boolean processEvent(InnerEvent msg) {
                if (msg.eventId== WHAT_NEED_AUTO_2_BOTTOM) {
                    needAuto2Bottom = true;
                }
                return false;
            }
        });

        assignViews();
        scrollView.setTouchEventListener(new Component.TouchEventListener() {
            @Override
            public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
                if(touchEvent.getAction() == TouchEvent.PRIMARY_POINT_DOWN){
                    uiHandler.removeEvent(WHAT_NEED_AUTO_2_BOTTOM);
                    needAuto2Bottom = false;
                }

                if(touchEvent.getAction() == TouchEvent.PRIMARY_POINT_UP
                || touchEvent.getAction() == TouchEvent.CANCEL){

                    uiHandler.removeEvent(WHAT_NEED_AUTO_2_BOTTOM);
                    uiHandler.sendEvent(WHAT_NEED_AUTO_2_BOTTOM,1000);
                }
                return false;
            }
        });
    }



    public void onClickDel(final Component view) {
        File file = new File(FileDownloadUtils.getDefaultSaveRootPath());
        if (!file.exists()) {
            return;
        }

        if (!file.isDirectory()) {
            return;
        }

        File[] files = file.listFiles();

        if (files == null) {
            updateDisplay(ResUtil.getString(this,ResourceTable.String_del_file_error_empty));
            return;
        }

        for (File file1 : files) {
            file1.delete();
            updateDisplay(String.format(ResUtil.getString(this,ResourceTable.String_hybrid_test_deleted_file),file1.getName()));
        }
    }

    private int totalCounts = 0;
    private int finalCounts = 0;

    // =================================================== demo area ========================================================

    /**
     * Start single download task
     * <p>
     * 启动单任务下载
     *
     * @param view
     */
    public void onClickStartSingleDownload(final Component view) {
        updateDisplay(String.format(ResUtil.getString(this,ResourceTable.String_hybrid_test_start_single_task),Constant.BIG_FILE_URLS[2]));
        totalCounts++;
        FileDownloader.getImpl().create(Constant.BIG_FILE_URLS[2])
                .setListener(createListener())
                .setTag(1)
                .start();
    }

    /**
     * Start multiple download tasks parallel
     * <p>
     * 启动并行多任务下载
     *
     * @param view
     */
    public void onClickMultiParallel(final Component view) {
        updateDisplay(String.format(ResUtil.getString(this,ResourceTable.String_hybrid_test_start_multiple_tasks_parallel),Constant.URLS.length));

        // 以相同的listener作为target，将不同的下载任务绑定起来
        final FileDownloadListener parallelTarget = createListener();
        final List<BaseDownloadTask> taskList = new ArrayList<>();
        int i = 0;
        for (String url : Constant.URLS) {
            taskList.add(FileDownloader.getImpl().create(url)
                    .setTag(++i));
        }
        totalCounts += taskList.size();

        new FileDownloadQueueSet(parallelTarget)
                .setCallbackProgressTimes(1)
                .downloadTogether(taskList)
                .start();
    }

    /**
     * Start multiple download tasks serial
     * <p>
     * 启动串行多任务下载
     *
     * @param view
     */
    public void onClickMultiSerial(final Component view) {
        updateDisplay(String.format(ResUtil.getString(this,ResourceTable.String_hybrid_test_start_multiple_tasks_serial),Constant.URLS.length));

        // 以相同的listener作为target，将不同的下载任务绑定起来
        final List<BaseDownloadTask> taskList = new ArrayList<>();
        final FileDownloadListener serialTarget = createListener();
        int i = 0;
        for (String url : Constant.URLS) {
            taskList.add(FileDownloader.getImpl().create(url)
                    .setTag(++i));
        }
        totalCounts += taskList.size();

        new FileDownloadQueueSet(serialTarget)
                .setCallbackProgressTimes(1)
                .downloadSequentially(taskList)
                .start();
    }

    private FileDownloadListener createListener() {
        return new FileDownloadListener() {

            @Override
            protected boolean isInvalid() {
                return isTerminating();
            }

            @Override
            protected void pending(final BaseDownloadTask task, final int soFarBytes, final int totalBytes) {
                updateDisplay(String.format("[pending] id[%d] %d/%d", task.getId(), soFarBytes, totalBytes));
            }

            @Override
            protected void connected(BaseDownloadTask task, String etag, boolean isContinue, int soFarBytes, int totalBytes) {
                super.connected(task, etag, isContinue, soFarBytes, totalBytes);
                updateDisplay(String.format("[connected] id[%d] %s %B %d/%d", task.getId(), etag, isContinue, soFarBytes, totalBytes));
            }

            @Override
            protected void progress(final BaseDownloadTask task, final int soFarBytes, final int totalBytes) {
                updateDisplay(String.format("[progress] id[%d] %d/%d", task.getId(), soFarBytes, totalBytes));
            }

            @Override
            protected void blockComplete(final BaseDownloadTask task) {
                MainHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        updateDisplay(String.format("[blockComplete] id[%d]", task.getId()));
                    }
                });
            }

            @Override
            protected void retry(BaseDownloadTask task, Throwable ex, int retryingTimes, int soFarBytes) {
                super.retry(task, ex, retryingTimes, soFarBytes);
                updateDisplay(String.format("[retry] id[%d] %s %d %d",
                        task.getId(), ex, retryingTimes, soFarBytes));
            }

            @Override
            protected void completed(BaseDownloadTask task) {
                finalCounts++;
                updateDisplay(String.format("[completed] id[%d] oldFile[%B]",
                        task.getId(),
                        task.isReusedOldFile()));
                updateDisplay(String.format("---------------------------------- %d", (Integer) task.getTag()));
            }

            @Override
            protected void paused(final BaseDownloadTask task, final int soFarBytes, final int totalBytes) {
                finalCounts++;
                updateDisplay(String.format("[paused] id[%d] %d/%d", task.getId(), soFarBytes, totalBytes));
                updateDisplay(String.format("############################## %d", (Integer) task.getTag()));
            }

            @Override
            protected void error(BaseDownloadTask task, Throwable e) {
                finalCounts++;
                updateDisplay(String.format("[error] id[%d] %s %s",
                        task.getId(),
                        e,
                        FileDownloadUtils.getStack(e.getStackTrace(), false)));

                updateDisplay(String.format("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! %d", (Integer) task.getTag()));
            }

            @Override
            protected void warn(BaseDownloadTask task) {
                finalCounts++;
                updateDisplay(String.format("[warn] id[%d]", task.getId()));
                updateDisplay(String.format("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ %d", (Integer) task.getTag()));
            }
        };
    }

    // -------------------------------------------------------- something just for display ------------------------------------------------------
    int lineCount = 0;

    private void updateDisplay(final CharSequence msg) {

        if (lineCount++ > 150) {
            lineCount = 0;
            downloadMsgTv.setText("");
        }
        downloadMsgTv.append(String.format("\n %s", msg));
        tipMsgTv.setText(String.format("%d/%d", finalCounts, totalCounts));
        if (needAuto2Bottom) {
            MainHandler.post(scroll2Bottom);
        }
    }

    private Runnable scroll2Bottom = new Runnable() {
        @Override
        public void run() {
            if (scrollView != null) {
                //scrollView.scrollTo(0,scrollView.getBottom());
                //scrollView.scrollTo(0,0);
                //scrollView.fullScroll(Component.FOCUS_DOWN);
                //scrollView.fu
            }
        }
    };

    @Override
    protected void onStop() {
        super.onStop();
        FileDownloader.getImpl().pauseAll();
    }

    private DirectionalLayout topGroup;
    private Button btDeleteAll,bt_single_task,bt_mulit_serial,bt_multi_parallel;
    private ScrollView scrollView;
    private Text downloadMsgTv;
    private Text tipMsgTv;

    private void assignViews() {
        topGroup = (DirectionalLayout) findComponentById(ResourceTable.Id_top_group);
        scrollView = (ScrollView) findComponentById(ResourceTable.Id_scrollView);
        downloadMsgTv = (Text) findComponentById(ResourceTable.Id_download_msg_tv);
        downloadMsgTv.setAutoScrollingCount(Text.AUTO_SCROLLING_FOREVER);
        tipMsgTv = (Text) findComponentById(ResourceTable.Id_tip_msg_tv);
        btDeleteAll = (Button) findComponentById(ResourceTable.Id_bt_delete_all);
        btDeleteAll.setClickedListener((view)->{onClickDel(view);});
        bt_single_task = (Button) findComponentById(ResourceTable.Id_bt_single_task);
        bt_single_task.setClickedListener((view->{onClickStartSingleDownload(view);}));
        bt_mulit_serial = (Button)findComponentById(ResourceTable.Id_bt_multi_task_serial);
        bt_mulit_serial.setClickedListener((view->{onClickMultiSerial(view);}));
        bt_multi_parallel = (Button)findComponentById(ResourceTable.Id_bt_multi_task_parallel);
        bt_multi_parallel.setClickedListener((view)->{onClickMultiParallel(view);});
    }
}
